#include <jni.h>
#include "native-lib.h"
#include "logger.h"
#include <iostream>
#include <malloc.h>
#include <string>


using namespace std;

/**
 *
 *  注册第一步
 *  动态注册
 */
static JNINativeMethod method[]{
        {"imageEncryp", "(Ljava/lang/String;Ljava/lang/String;)V", (void *) imageEncryp},
        {"imageDncryp", "(Ljava/lang/String;Ljava/lang/String;)V", (void *) imageDncryp},
        {"fileSplit", "(Ljava/lang/String;I)[Ljava/lang/String;", (char **) fileSplit},
        {"fileMerge", "([Ljava/lang/String;Ljava/lang/String;)V", (void *) fileMerge}


};

/**
 * 注册第二步
 * @param env
 * @return
 */
static int registerNatives(JNIEnv *env) {
    jclass clazz;
    clazz = env->FindClass("com/example/ndkimage/ImageEncrypDecryp");
    if (clazz == NULL) {
        return JNI_FALSE;
    }
    if (env->RegisterNatives(clazz, method, sizeof(method) / sizeof(method[0])) < 0) {
        return JNI_FALSE;
    }
    return JNI_TRUE;
}


/**
 * 注册第三步
 * @param env
 * @return
 */
JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) {
    JNIEnv *env = NULL;
    jint result = -1;
    if (vm->GetEnv((void **) &env, JNI_VERSION_1_6) != JNI_OK) {
        return -1;
    }
    if (env != NULL) {
        registerNatives(env);
    } else {
        return -1;
    }
    return JNI_VERSION_1_6;
}


void imageEncryp(JNIEnv *env,jobject obj, jstring url, jstring des) {
    const char* c_src = env->GetStringUTFChars(url,0);
    const char* c_drc = env->GetStringUTFChars(des,0);
    LOGE("%s", c_src);
    LOGE("%s", c_drc);
    FILE *fSrc = fopen(c_src,"rb");
    FILE *fDes = fopen(c_drc,"wb");
    if (NULL == fSrc){
        LOGE("源文件空");
        return;
    }
    int c;
    while ((c = fgetc(fSrc)) != EOF){
        fputc(c^5,fDes);
    }
    fclose(fSrc);
    fclose(fDes);
}


void imageDncryp(JNIEnv *env,jobject obj, jstring url, jstring des) {
    const char* c_src = env->GetStringUTFChars(url,0);
    const char* c_drc = env->GetStringUTFChars(des,0);
    LOGE("%s", c_src);
    LOGE("%s", c_drc);
    FILE *fSrc = fopen(c_src,"rb");
    FILE *fDes = fopen(c_drc,"wb");
    if (NULL == fSrc){
        LOGE("源文件空");
        return;
    }
    int c;
    while ((c = fgetc(fSrc)) != EOF){
        fputc(c^5,fDes);
    }
    fclose(fSrc);
    fclose(fDes);
}


long getFileSize(const char* fileName){
    FILE *file = fopen(fileName,"rw");
    if (!file){
        return 0;
    }
    fseek(file,0,SEEK_END);
    long size =  ftell(file);
    fclose(file);
    return size;
}


long getFile(FILE* file){
    if (!file){
        return 0;
    }
    fseek(file,0,SEEK_END);
    long size =  ftell(file);
    fseek(file,0,SEEK_SET);
    return size;
}

char** fileSplit(JNIEnv *env,jobject obj, jstring url, jint nums) {
    const char* c_src = env->GetStringUTFChars(url,0);
    long fileSize = getFileSize(c_src);
    FILE *file = fopen(c_src,"rw");
    // 二维数组
    char** file_names = (char **)malloc(sizeof(char*) * nums);
    //每份大小
    long perFileSize =  fileSize / nums;
    for (int i = 0; i < nums; i++) {
        file_names[i] = (char*)malloc(sizeof(char*) * 512*100);
        sprintf(file_names[i],"/storage/emulated/0/DCIM/Camera/%d",i);
    }
    for (long h = 0; h < nums; h++) {
        FILE *cur_File = fopen(file_names[h],"wb");
        long start = h * perFileSize;
        long end = (h + 1) * perFileSize;
        if (h == nums - 1){
            end = fileSize;
        }

        for (long a = start; a < end; a++) {
            fputc(fgetc(file),cur_File);
        }
        fclose(cur_File);
        free(file_names[h]);
    }
    fclose(file);
    free(file_names);
    return NULL;
}

void fileMerge(JNIEnv *env,jobject obj,jobjectArray res, jstring url) {
    LOGE("fileMerge");
    const char *str = env->GetStringUTFChars(url, NULL);
    LOGE("const char:%s", str);

    jsize size = env->GetArrayLength(res);

    string urls[size];

    for (int i = 0; i < size; i++) {
        jstring obj = (jstring) env->GetObjectArrayElement(res,i);
        const char * str = env -> GetStringUTFChars(obj,0);
        urls[i] = str;
        env -> ReleaseStringUTFChars(obj,str);
    }
    long statr = 0;
    long end = 0;
    FILE *fileMerge = fopen(str, "wb");
    for (int i = 0; i < urls->size(); i++) {
        FILE *perFile;
        perFile = fopen(const_cast<char *>(urls[i].c_str()), "rb");
        statr = end;
        end += getFile(perFile);
        for (long t = statr; t < end; t++) {
            fputc(fgetc(perFile), fileMerge);
        }
        if(NULL != perFile){
            fclose(perFile);
        }
    }
    if (NULL != fileMerge){
        fclose(fileMerge);
    }

}








